import React, { useRef, useState, useEffect } from 'react';
import { Button, Upload, message } from 'antd';
import { InboxOutlined } from '@ant-design/icons';
import SparkMD5 from 'spark-md5';
import { initializeOSS, getOSSClient, checkOSSConnection } from '../../utils/oss';
import AA from '../../compages/aa/Index';

const CHUNK_SIZE = 5 * 1024 * 1024; // 5MB

// 计算文件内容 hash（异步，适合大文件）
// 定义一个异步函数，用于计算文件的哈希值
const calcHash = async (file: File, onProgress?: (percent: number) => void) => {
  // 返回一个Promise对象
  return new Promise<string>((resolve, reject) => {
    // 定义每个分块的大小
    const chunkSize = CHUNK_SIZE;
    // 计算文件的总块数
    const chunks = Math.ceil(file.size / chunkSize);
    // 当前处理的块数
    let currentChunk = 0;
    // 创建一个SparkMD5对象，用于计算哈希值
    const spark = new SparkMD5.ArrayBuffer();
    // 创建一个FileReader对象，用于读取文件
    const fileReader = new FileReader();

    // 文件读取成功的回调函数
    fileReader.onload = (e) => {
      // 如果读取成功，则将读取到的数据添加到SparkMD5对象中
      if (e.target && e.target.result) {
        spark.append(e.target.result as ArrayBuffer);
        // 更新当前处理的块数
        currentChunk++;
        // 如果有进度回调函数，则调用进度回调函数
        if (onProgress) onProgress(Math.floor((currentChunk / chunks) * 100));
        // 如果还有未处理的块，则继续处理下一个块
        if (currentChunk < chunks) {
          loadNext();
        } else {
          // 如果所有块都处理完毕，则返回计算得到的哈希值
          resolve(spark.end());
        }
      }
    };

    // 文件读取失败的回调函数
    fileReader.onerror = () => reject('文件读取失败');

    // 定义一个函数，用于处理下一个块
    function loadNext() {
      // 计算当前块的起始位置和结束位置
      const start = currentChunk * chunkSize;
      const end = Math.min(file.size, start + chunkSize);
      // 使用FileReader对象读取当前块的数据
      fileReader.readAsArrayBuffer(file.slice(start, end));
    }

    // 开始处理第一个块
    loadNext();
  });
};

// 上传成功后记录 hash
const markFileUploaded = (hash: string) => {
  const list = JSON.parse(localStorage.getItem('upload-success-hash-list') || '[]');
  if (!list.includes(hash)) {
    list.push(hash);
    localStorage.setItem('upload-success-hash-list', JSON.stringify(list));
  }
};

// 检查文件是否已上传（基于hash）
const checkFileExists = (hash: string): boolean => {
  const list = JSON.parse(localStorage.getItem('upload-success-hash-list') || '[]');
  return list.includes(hash);
};

// 生成文件名
const generateFileName = (originalName: string): string => {
  const timestamp = Date.now();
  const random = Math.random().toString(36).substring(2, 15);
  const extension = originalName.split('.').pop();
  return `files/${timestamp}_${random}.${extension}`;
};

function Index() {
  const [file, setFile] = useState<File | null>(null);
  const [uploading, setUploading] = useState(false);
  const [progress, setProgress] = useState(0); // 保留用于AA组件
  const [paused, setPaused] = useState(false);
  const [resumeFlag, setResumeFlag] = useState(0);
  const uploadState = useRef({ paused: false });
  const [fileHash, setFileHash] = useState<string>('');

  // 初始化OSS
  useEffect(() => {
    const initOSS = async () => {
      try {
        initializeOSS();
        // 测试OSS连接
        const isConnected = await checkOSSConnection();
        if (isConnected) {
          message.success('OSS连接初始化成功');
        } else {
          message.warning('OSS连接测试失败，但可能仍可正常使用');
        }
      } catch (error) {
        message.error('OSS连接初始化失败，请检查配置');
        console.error('OSS初始化失败:', error);
      }
    };
    
    initOSS();
  }, []);

  // 选择文件时先本地hash秒传判断
  const beforeUpload = async (file: File) => {
    // 设置文件
    setFile(file);
    setProgress(0);
    setPaused(false);
    uploadState.current.paused = false;
    setFileHash('');
    
    // 计算 hash
    const hash = await calcHash(file);
    setFileHash(hash);
    
    // 检查是否已上传过
    if (checkFileExists(hash)) {
      message.success('文件已上传过，秒传成功！');
      setProgress(100);
      return false;
    }
    return false;
  };

  // 上传到OSS（支持大文件）
  const handleUpload = async () => {
    if (!file) return;
    
    setUploading(true);
    setPaused(false);
    setProgress(0);
    
    try {
      // 计算hash
      const hash = fileHash || await calcHash(file, percent => setProgress(Math.floor(percent * 0.2)));
      setFileHash(hash);
      setProgress(10);
      
      // 检查文件是否已存在
      if (checkFileExists(hash)) {
        message.success('文件已存在，秒传成功！');
        setProgress(100);
        setUploading(false);
        return;
      }
    
      // 直接上传到OSS
      const client = getOSSClient();
      const fileName = generateFileName(file.name);
      
      console.log('开始上传文件到OSS:', fileName, '文件大小:', file.size);
      
      setProgress(30);
      
      // 上传文件
      const result = await client.put(fileName, file);
      
      console.log('文件上传成功:', result.url);
      
      // 记录上传成功
      markFileUploaded(hash);
      setProgress(100);
      setUploading(false);
      message.success('上传成功！');
      
    } catch (error) {
      setUploading(false);
      setPaused(true);
      message.error(`上传失败: ${error instanceof Error ? error.message : '未知错误'}`);
      console.error('上传失败:', error);
    }
  };

  // 恢复上传
  const handleResume = () => {
    setResumeFlag(flag => flag + 1);
    setUploading(true);
    setPaused(false);
    uploadState.current.paused = false;
  };

  // 监听恢复
  useEffect(() => {
    if (resumeFlag > 0 && file && !uploading) {
      handleUpload();
    }
    // eslint-disable-next-line
  }, [resumeFlag]);

  return (
    <div style={{ maxWidth: 600, margin: '40px auto', padding: 32, background: '#fff', borderRadius: 12, boxShadow: '0 2px 16px #eee' }}>
      <h2 style={{ textAlign: 'center', marginBottom: 24, color: '#1890ff' }}>文件上传到阿里云OSS</h2>
      
      <Upload.Dragger
        beforeUpload={beforeUpload}
        showUploadList={false}
        accept='*'
        disabled={uploading}
        style={{ marginBottom: 24 }}
      >
        <p className="ant-upload-drag-icon">
          <InboxOutlined />
        </p>
        <p>点击或拖拽文件到此处上传到阿里云OSS</p>
        <p style={{ fontSize: '12px', color: '#999' }}>支持大文件、断点续传、秒传</p>
        {file && <p style={{ color: '#1890ff' }}>{file.name} ({(file.size / 1024 / 1024).toFixed(2)}MB)</p>}
      </Upload.Dragger>
      
      <Button
        type="primary"
        block
        disabled={!file || uploading}
        loading={uploading}
        onClick={handleUpload}
        style={{ marginBottom: 16 }}
      >
        {uploading ? '上传中...' : '开始上传到OSS'}
      </Button>
      
      <Button
        block
        danger
        disabled={!uploading || paused}
        onClick={() => { setPaused(true); uploadState.current.paused = true; }}
        style={{ marginBottom: 8 }}
      >
        暂停上传
      </Button>
      
      <Button
        block
        type="dashed"
        disabled={uploading || !paused}
        onClick={handleResume}
        style={{ marginBottom: 16 }}
      >
        继续上传
      </Button>
      
      <AA progress={progress} />
      
      {fileHash && (
        <div style={{ marginTop: 16, padding: 12, background: '#f5f5f5', borderRadius: 4 }}>
          <p style={{ margin: 0, fontSize: '12px', color: '#666' }}>
            <strong>文件Hash:</strong> {fileHash.substring(0, 16)}...
          </p>
        </div>
      )}

      {/* <AA /> */}
    </div>
  );
}

export default Index;